(function (window, T) {
    var util = T.util = {};

    T.$$ = window['$T$'] = window['$T$'] || {global:{}};

    T.$$._counter = T.$$._counter || 1;

    /**
     * 获取唯一标识
     * @return guid
     */
    util.guid = function () {
        return '$TANGRAM$' + T.$$._counter ++;
    };
    /**
     * 判断目标参数是否Array对象
     * @name util.isArray
     * @function
     * @grammar util.isArray(source)
     * @param {Any} source 目标参数
     * @meta standard
     * @see util.isString,util.isObject,util.isNumber,util.isElement,util.isBoolean,util.isDate
     *             
     * @returns {boolean} 类型判断结果
     */
    util.isArray = function (source) {
        return '[object Array]' == Object.prototype.toString.call(source);
    };

    /**
     * 判断目标参数是否Boolean对象
     * @name util.isBoolean
     * @function
     * @grammar util.isBoolean(source)
     * @param {Any} source 目标参数
     * @version 1.3
     * @see util.isString,util.isObject,util.isNumber,util.isElement,util.isArray,util.isDate
     *             
     * @returns {boolean} 类型判断结果
     */
    util.isBoolean = function(o) {
        return typeof o === 'boolean';
    };

    /**
     * 判断目标参数是否为Element对象
     * @name util.isElement
     * @function
     * @grammar util.isElement(source)
     * @param {Any} source 目标参数
     * @meta standard
     * @see util.isString,util.isObject,util.isNumber,util.isArray,util.isBoolean,util.isDate
     *             
     * @returns {boolean} 类型判断结果
     */
    util.isElement = function (source) {
        return !!(source && source.nodeName && source.nodeType == 1);
    };


    /**
     * 判断目标参数是否为Date对象
     * @name util.isDate
     * @function
     * @grammar util.isDate(source)
     * @param {Any} source 目标参数
     * @version 1.3
     * @see util.isString,util.isObject,util.isNumber,util.isArray,util.isBoolean,util.isElement
     *             
     * @returns {boolean} 类型判断结果
     */
    util.isDate = function(o) {
        // return o instanceof Date;
        return {}.toString.call(o) === "[object Date]" && o.toString() !== 'Invalid Date' && !isNaN(o);
    };

    /**
     * 判断目标参数是否为function或Function实例
     * @name util.isFunction
     * @function
     * @grammar util.isFunction(source)
     * @param {Any} source 目标参数
     * @version 1.2
     * @see util.isString,util.isObject,util.isNumber,util.isArray,util.isElement,util.isBoolean,util.isDate
     * @meta standard
     * @returns {boolean} 类型判断结果
     */
    util.isFunction = function (source) {
        // chrome下,'function' == typeof /a/ 为true.
        return '[object Function]' == Object.prototype.toString.call(source);
    };

    /**
     * 判断目标参数是否number类型或Number对象
     * @name util.isNumber
     * @function
     * @grammar util.isNumber(source)
     * @param {Any} source 目标参数
     * @meta standard
     * @see util.isString,util.isObject,util.isArray,util.isElement,util.isBoolean,util.isDate
     *             
     * @returns {boolean} 类型判断结果
     * @remark 用本函数判断NaN会返回false，尽管在Javascript中是Number类型。
     */
    util.isNumber = function (source) {
        return '[object Number]' == Object.prototype.toString.call(source) && isFinite(source);
    };

    /**
     * 判断目标参数是否为Object对象
     * @name util.isObject
     * @function
     * @grammar util.isObject(source)
     * @param {Any} source 目标参数
     * @shortcut isObject
     * @meta standard
     * @see util.isString,util.isNumber,util.isArray,util.isElement,util.isBoolean,util.isDate
     *             
     * @returns {boolean} 类型判断结果
     */
    util.isObject = function (source) {
        return 'function' == typeof source || !!(source && 'object' == typeof source);
    };

    /**
     * 判断目标参数是否string类型或String对象
     * @name util.isString
     * @function
     * @grammar util.isString(source)
     * @param {Any} source 目标参数
     * @shortcut isString
     * @meta standard
     * @see util.isObject,util.isNumber,util.isArray,util.isElement,util.isBoolean,util.isDate
     *             
     * @returns {boolean} 类型判断结果
     */
    util.isString = function (source) {
        return '[object String]' == Object.prototype.toString.call(source);
    };
    /**
     * Tangram继承机制提供的一个基类，用户可以通过继承util.Class来获取它的属性及方法。
     * @class
     * @name    util.Class
     * @grammar util.Class(guid)
     * @param   {string}    guid    对象的唯一标识
     * @meta standard
     * @remark util.Class和它的子类的实例均包含一个全局唯一的标识guid。guid是在构造函数中生成的，因此，继承自util.Class的类应该直接或者间接调用它的构造函数。<br>util.Class的构造函数中产生guid的方式可以保证guid的唯一性，及每个实例都有一个全局唯一的guid。
     * @meta standard
     * @see util.inherits,util.Event
     */
    util.Class = function() {
        this.guid = util.guid();

        !this.__decontrolled && (T.$$._instances[this.guid] = this);
    };

    T.$$._instances = T.$$._instances || {};

    /**
     * 释放对象所持有的资源，主要是自定义事件。
     * @name dispose
     * @grammar obj.dispose()
     * TODO: 将_listeners中绑定的事件剔除掉
     */
    util.Class.prototype.dispose = function(){
        delete T.$$._instances[this.guid];

        // this.__listeners && (for (var i in this.__listeners) delete this.__listeners[i]);

        for(var property in this){
            typeof this[property] != "function" && delete this[property];
        }
        this.disposed = true;   // 20100716
    };

    /**
     * 重载了默认的toString方法，使得返回信息更加准确一些。
     * 20111219 meizz 为支持老版本的className属性，以后统一改成 __type
     * @return {string} 对象的String表示形式
     */
    util.Class.prototype.toString = function(){
        return "[object " + (this.__type || this._className || "Object") + "]";
    };

    /**
     * util
     */
    /**
     * 为类型构造器建立继承关系
     * @name T.util.inherits
     * @function
     * @grammar T.util.inherits(subClass, superClass[, type])
     * @param {Function} subClass 子类构造器
     * @param {Function} superClass 父类构造器
     * @param {string} type 类名标识
     * @remark
     * 
    使subClass继承superClass的prototype，因此subClass的实例能够使用superClass的prototype中定义的所有属性和方法。<br>
    这个函数实际上是建立了subClass和superClass的原型链集成，并对subClass进行了constructor修正。<br>
    <strong>注意：如果要继承构造函数，需要在subClass里面call一下，具体见下面的demo例子</strong>
        
     * @shortcut inherits
     * @meta standard
     * @see T.util.Class
     */
    util.inherits = function (subClass, superClass, type) {
        var key, proto, 
            selfProps = subClass.prototype, 
            clazz = new Function();
            
        clazz.prototype = superClass.prototype;
        proto = subClass.prototype = new clazz();

        for (key in selfProps) {
            proto[key] = selfProps[key];
        }
        subClass.prototype.constructor = subClass;
        subClass.superClass = superClass.prototype;

        // 类名标识，兼容Class的toString，基本没用
        typeof type == "string" && (proto.__type = type);

        subClass.extend = function(json) {
            for (var i in json) proto[i] = json[i];
            return subClass;
        }
        
        return subClass;
    };

    /**
     * 将一个变量转换成array
     * @name T.util.toArray
     * @function
     * @grammar T.util.toArray(source)
     * @param {mix} source 需要转换成array的变量
     * @version 1.3
     * @meta standard
     * @returns {array} 转换后的array
     */
    util.toArray = function (source) {
        if (source === null || source === undefined)
            return [];
        if (util.isArray(source))
            return source;

        // The strings and functions also have 'length'
        if (typeof source.length !== 'number' || typeof source === 'string' || util.isFunction(source)) {
            return [source];
        }

        //nodeList, IE 下调用 [].slice.call(nodeList) 会报错
        if (source.item) {
            var l = source.length, array = new Array(l);
            while (l--)
                array[l] = source[l];
            return array;
        }

        return [].slice.call(source);
    };

    /**
     * shortcut
     */
    T.inherits = T.util.inherits;
})(window, T);